package com.atguigu.gmall.product.service.impl;

import com.atguigu.gmall.product.entity.*;
import com.atguigu.gmall.product.service.*;
import com.atguigu.gmall.starter.cache.service.CacheService;
import com.atguigu.gmall.weball.vo.CategoryTreeVo;

import java.util.Date;

import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.feign.search.SearchFeignCilent;
import com.atguigu.gmall.product.vo.SkuInfoVo;
import com.atguigu.gmall.search.Goods;
import com.atguigu.gmall.search.SearchAttr;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.gmall.product.mapper.SkuInfoMapper;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author weiranyi
 * @description 针对表【sku_info(库存单元表)】的数据库操作Service实现
 * @createDate 2022-11-29 16:41:28
 */
@Service
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoMapper, SkuInfo>
        implements SkuInfoService {
    @Autowired
    SkuAttrValueService skuAttrValueService;
    @Autowired
    SkuImageService skuImageService;
    @Autowired
    SkuSaleAttrValueService skuSaleAttrValueService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Page<SkuInfo> getSkuList(long pn, long ps) {
        Page<SkuInfo> skuInfoPage = new Page<>(pn, ps);
        this.page(skuInfoPage);
        return skuInfoPage;
    }

    @Transactional
    @Override
    public void saveSkuInfo(SkuInfoVo skuInfoVo) {
        // 1.保存到sku_info基本信息
        SkuInfo skuInfo = new SkuInfo();
        BeanUtils.copyProperties(skuInfoVo, skuInfo);
        this.save(skuInfo);
        //-拿到自增的id
        Long skuId = skuInfo.getId();

        // 2.skuAttrValueList -> sku_attr_value
        List<SkuInfoVo.SkuAttrValueListDTO> skuAttrValueList = skuInfoVo.getSkuAttrValueList();
//        ArrayList<SkuAttrValue> skuAttrValues = new ArrayList<>();
//        for (SkuInfoVo.SkuAttrValueListDTO skuAttrValueDTO : skuAttrValueList) {
//            SkuAttrValue skuAttrValue = new SkuAttrValue();
//            // attrId,valueId
//            BeanUtils.copyProperties(skuAttrValueDTO, skuAttrValue);
//            skuAttrValue.setSkuId(skuId);
//            skuAttrValues.add(skuAttrValue);
//        }
        List<SkuAttrValue> skuAttrValues = skuAttrValueList.stream().map(item -> {
            SkuAttrValue skuAttrValue = new SkuAttrValue();
            // attrId,valueId
            BeanUtils.copyProperties(item, skuAttrValue);
            skuAttrValue.setSkuId(skuId);
            return skuAttrValue;
        }).collect(Collectors.toList());
        skuAttrValueService.saveBatch(skuAttrValues);

        // 3.skuSaleAttrValueList -> sku_sale_attr_value
        List<SkuInfoVo.SkuSaleAttrValueListDTO> skuSaleAttrValueList = skuInfoVo.getSkuSaleAttrValueList();
//        ArrayList<SkuSaleAttrValue> skuSaleAttrValues = new ArrayList<>();
//        for (SkuInfoVo.SkuSaleAttrValueListDTO skuSaleAttrValueDTO : skuSaleAttrValueList) {
//            // 传入：saleAttrValueId saleAttrValueName baseSaleAttrId saleAttrName
//            // 需要：skuId spuId saleAttrValueId
//            SkuSaleAttrValue skuSaleAttrValue = new SkuSaleAttrValue();
//            skuSaleAttrValue.setSkuId(skuId);
//            skuSaleAttrValue.setSpuId(skuInfoVo.getSpuId());
//            skuSaleAttrValue.setSaleAttrValueId(skuSaleAttrValueDTO.getSaleAttrValueId());
//            skuSaleAttrValues.add(skuSaleAttrValue);
//        }
        List<SkuSaleAttrValue> skuSaleAttrValues = skuSaleAttrValueList.stream().map(item -> {
            // 传入：saleAttrValueId saleAttrValueName baseSaleAttrId saleAttrName
            // 需要：skuId spuId saleAttrValueId
            SkuSaleAttrValue skuSaleAttrValue = new SkuSaleAttrValue();
            skuSaleAttrValue.setSkuId(skuId);
            skuSaleAttrValue.setSpuId(skuInfoVo.getSpuId());
            skuSaleAttrValue.setSaleAttrValueId(item.getSaleAttrValueId());
            return skuSaleAttrValue;
        }).collect(Collectors.toList());
        skuSaleAttrValueService.saveBatch(skuSaleAttrValues);

        // 4.skuImageList -> sku_image
        List<SkuInfoVo.SkuImageListDTO> skuImageList = skuInfoVo.getSkuImageList();
//        ArrayList<SkuImage> skuImages = new ArrayList<>();
//        for (SkuInfoVo.SkuImageListDTO skuImageDTO : skuImageList) {
//            SkuImage skuImage = new SkuImage();
//            //spuImgId imgName imgUrl isDefault
//            BeanUtils.copyProperties(skuImageDTO, skuImage);
//            skuImage.setSkuId(skuId);
//            skuImages.add(skuImage);
//        }
        List<SkuImage> skuImages = skuImageList.stream().map(item -> {
            SkuImage skuImage = new SkuImage();
            //spuImgId imgName imgUrl isDefault
            BeanUtils.copyProperties(item, skuImage);
            skuImage.setSkuId(skuId);
            return skuImage;
        }).collect(Collectors.toList());
        skuImageService.saveBatch(skuImages);

        //同步到bitmap位图
        stringRedisTemplate.opsForValue().setBit(RedisConst.BITMAP_SKU_NAME, skuId, true);
    }

    // 远程-ES SearchFeignCilent
    @Autowired
    private SearchFeignCilent searchFeignCilent;
    @Autowired
    private BaseTrademarkService baseTrademarkService;
    @Autowired
    private BaseCategory1Service baseCategory1Service;
    @Autowired
    CacheService cacheService;
    @Autowired
    RedissonClient redissonClient;

    @Transactional
    @Override
    public void onSale(Long skuId) {
        //1
        this.toggleSaleStatus(skuId, 1);

        Goods goods = getGoodsFromDatabase(skuId);
        //远程上架操作-ES==========================================
        searchFeignCilent.upGoodsToES(goods);
        // 位图设置为0
        stringRedisTemplate.opsForValue().setBit(RedisConst.BITMAP_SKU_NAME, skuId, true);
    }

    private Goods getGoodsFromDatabase(Long skuId) {
        // 1.查询skuinfo
        SkuInfo skuInfo = this.getById(skuId);
        // 封装一个Goods
        Goods goods = new Goods();
        goods.setId(skuInfo.getId());
        goods.setDefaultImg(skuInfo.getSkuDefaultImg());
        goods.setTitle(skuInfo.getSkuName());
        goods.setPrice(skuInfo.getPrice().doubleValue());
        goods.setCreateTime(new Date());
        // 品牌id
        Long tmId = skuInfo.getTmId();
        BaseTrademark trademark = baseTrademarkService.getById(tmId);
        goods.setTmId(tmId); //品牌id
        goods.setTmName(trademark.getTmName());
        goods.setTmLogoUrl(trademark.getLogoUrl());
        // 精确的标题
        CategoryTreeVo categoryTree = baseCategory1Service.getCategoryTreeVoByC3Id(skuInfo.getCategory3Id());
        goods.setCategory1Id(categoryTree.getCategoryId());
        goods.setCategory1Name(categoryTree.getCategoryName());
        CategoryTreeVo categoryTreeVo2 = categoryTree.getCategoryChild().get(0);
        goods.setCategory2Id(categoryTreeVo2.getCategoryId());
        goods.setCategory2Name(categoryTreeVo2.getCategoryName());
        CategoryTreeVo categoryTreeVo3 = categoryTreeVo2.getCategoryChild().get(0);
        goods.setCategory3Id(categoryTreeVo3.getCategoryId());
        goods.setCategory3Name(categoryTreeVo3.getCategoryName());
        // 热点数据暂时为0
        goods.setHotScore(0L);
        // Goods.attrs - 获取sku对应的所有平台属性
        List<SearchAttr> searchAttrList = skuAttrValueService.getSearchAttrBySkuAttrsAndValue(skuId);
        goods.setAttrs(searchAttrList);
        return goods;
    }

    @Transactional
    @Override
    public void cancelSale(Long skuId) {
        //0
        this.toggleSaleStatus(skuId, 0);
        //远程下架远程-ES==========================================
        searchFeignCilent.downGoodsToES(skuId);
        //清除缓存数据
        cacheService.delayDoubleDelete(RedisConst.CACHE_SKU_DETAIL_PREFIX + skuId);
        // 位图设置为0
        stringRedisTemplate.opsForValue().setBit(RedisConst.BITMAP_SKU_NAME, skuId, false);
    }


    private void toggleSaleStatus(Long skuId, int i) {
        SkuInfo skuInfo = new SkuInfo();
        skuInfo.setId(skuId);
        skuInfo.setIsSale(i);
        this.updateById(skuInfo);
    }

}




